﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class ModuleManager
{
    private readonly OwnerObj ownerObj = null;

    private Dictionary<Type, IModBase> modules = new Dictionary<Type, IModBase>();

    private List<Type> removeModules = new List<Type>();

    public ModuleManager(OwnerObj ownerObj)
    {
        this.ownerObj = ownerObj;
    }

    /// <summary>
    /// 创建类工厂
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <returns></returns>
    private IModBase CreateFactory<T>() where T : IModBase
    {
        if (typeof(T) == typeof(ModAction))
        {
            return new ModAction(ownerObj);
        }
        else if (typeof(T) == typeof(ModAttr))
        {
            return new ModAttr(ownerObj);
        }
        else if (typeof(T) == typeof(ModDamage))
        {
            return new ModDamage(ownerObj);
        }
        else if (typeof(T) == typeof(ModAI))
        {
            return new ModAI(ownerObj);
        }
        else if (typeof(T) == typeof(ModBlood))
        {
            return new ModBlood(ownerObj);
        }
        else
        {
            return default(T);
        }
    }

    /// <summary>
    /// 获取IModBase
    /// </summary>
    /// <param name="modName"></param>
    /// <returns></returns>
    public T Get<T>()
    {
        if (modules.ContainsKey(typeof(T)))
        {
            return (T)((object)modules[typeof(T)]);
        }

        return default(T);
    }

    public T GetOrNew<T>() where T : IModBase
    {
        if (modules.ContainsKey(typeof(T)))
        {
            return (T)modules[typeof(T)];
        }
        else
        {
            IModBase newModBase = CreateFactory<T>();

            newModBase.SetModule(this);
            newModBase.Load();

            modules.Add(typeof(T), newModBase);

            return (T)newModBase;
        }
    }

    public void Remove<T>() where T : IModBase
    {
        if (!removeModules.Contains(typeof(T)))
        {
            removeModules.Add(typeof(T));
        }
    }

    public void RemoveAll()
    {
        foreach (IModBase modBase in modules.Values)
        {
            removeModules.Remove(modBase.GetType());
        }
    }

    public void RemoveAllNow()
    {
        foreach (IModBase modBase in modules.Values)
        {
            modBase.UnLoad();
        }

        modules.Clear();
    }

    public void Update(float deltaTime)
    {
        foreach (Type removeType in removeModules)
        {
            modules.Remove(removeType);
        }

        removeModules.Clear();

        foreach (IModBase modBase in modules.Values) {
            modBase.Update(deltaTime);
        }
    }

}
